package ldh.im.fxgui.pane;

import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import ldh.im.ImConfig;
import ldh.im.dto.enums.MessageType;
import ldh.im.fxbase.controller.ImagePageController;
import ldh.im.fxbase.dao.ImMessageDao;
import ldh.im.fxbase.data.pojo.MessageExt;
import ldh.im.fxbase.data.pojo.status.ImMessageFileStatus;
import ldh.im.fxbase.exception.ImageNoDownloadException;
import ldh.im.fxbase.data.pojo.ImMessage;
import ldh.im.fxbase.service.GifViewService;
import ldh.im.fxbase.util.*;
import ldh.im.fxgui.component.ImStage;
import ldh.im.fxgui.service.DefaultFileProgressListener;
import ldh.im.fxgui.util.ImageUtil;
import ldh.im.fxgui.util.UiUtil;
import ldh.rpc.cache.CacheService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;

/**
 * 图片面板
 */
public class ImageMessagePane extends BaseMessagePane {

    private static final Logger LOGGER = LoggerFactory.getLogger(ImageMessagePane.class);

    private ImMessageDao imMessageDao = new ImMessageDao();
    private GifViewService gifViewService = null;

    @Override
    public Node createPane(ImMessage message, boolean isReceive, boolean isRef) {
        if (message.getMessageType() != MessageType.Image) {
            throw new RuntimeException("不支持这种消息类型" + message.getMessageType());
        }
        CacheService cacheService = RpcUtil.getRpcBootstrap().getRpcConfig().getCacheService();
        String userId = (String) cacheService.getCache(ImConfig.LOGIN_USER_ID);
        if (!message.isSender(userId) && message.getFileStatus() != ImMessageFileStatus.downloaded) {
            Label label = buildLabel(message, userId, isRef);
            return label;
        }

        Node node = createImageView(message, isRef);
        node.getStyleClass().add("message-item-image");
        return  node;
    }

    public void reset() {
        if (gifViewService != null) {
            gifViewService.reset();
        }
    }

    public void update() {
        if (gifViewService != null) {
            gifViewService.update();
        }
    }

    public void dispose() {
        if (gifViewService != null) {
            gifViewService.dispose();
        }
    }

    private Label buildLabel(ImMessage message, String userId, boolean isRef) {
        Label label = new Label("图片正在下载中");
        label.setPadding(new Insets(10, 5, 10, 5));

        if (!isRef) {
            label.setOnMouseClicked(e->{
                ThreadPoolUtil.submit(()->{
                    ExceptionUtil.catchException(()->{
                        ImMessage imMessage = imMessageDao.getMessageByServerId(userId, message.getServerId());
                        if (imMessage.getFileStatus() == ImMessageFileStatus.downloaded) {
                            FxThreadUtil.runLater(()->UiUtil.uiUpdateMessage(imMessage));
                        } else {
                            RpcUtil.getImService().downloadFile(message, new DefaultFileProgressListener(), m-> UiUtil.uiUpdateMessage(m));
                        }
                        return null;
                    }, "下载图片");
                });

            });
        }
        return label;
    }

    private Node createImageView(ImMessage message, boolean isRef) {
        String imagePath = null;
        StackPane stackPane = new StackPane();
        stackPane.setMaxHeight(300);
        try {
            ImageView imageView = new ImageView();
            Rectangle clip = new Rectangle();
            clip.widthProperty().bind(imageView.fitWidthProperty());
            clip.heightProperty().bind(imageView.fitHeightProperty());
            clip.setArcWidth(15);
            clip.setArcHeight(15);
            imageView.setClip(clip);

            if (message.getMessageExt() == null) {
                message.initExt();
            }
            MessageExt messageExt = message.getMessageExt();
            double imageWidth = messageExt.getImageWidth();
            double imageHeight = messageExt.getImageHeight();
            double fitImageWidth = ImageUtil.calcFitImageWidth(ParamUtil.MESSAGE_WIDTH-100, imageWidth, imageHeight);
            double fitImageHeight = ImageUtil.calcFitImageHeight(fitImageWidth, imageWidth, imageHeight);
            imageView.setFitWidth(fitImageWidth);
            imageView.setFitHeight(fitImageHeight);

            imagePath = FileUtil.getFilePath(message);
            if (!ImageUtil.isGif(imagePath)) {
                Image image = ImageUtil.getCacheImage(imagePath);
                imageView.setImage(image);

                setImage(imageView, image, message, isRef);
            } else {
                gifViewService = new GifViewService(imagePath);
                ThreadPoolUtil.submit(()->{
                    Image image = gifViewService.getFirstImage();
                    FxThreadUtil.runLater(()->{
                        imageView.setImage(image);
                        setImage(imageView, image, message, isRef);
                    });
                    gifViewService.animateView(imageView);
                });
            }

            imageView.setPreserveRatio(true);

            imageView.setOnMouseEntered(e-> imageView.setCursor(Cursor.HAND));
            imageView.setOnMouseExited(e-> imageView.setCursor(Cursor.DEFAULT));

            imageView.setOnMouseClicked(e->{
                if (e.getClickCount() != 2) return;
                ImStage stage = new ImStage();
                stage.setTitle("图片预览");
                stage.getCurrentScene().getStylesheets().add(this.getClass().getResource("/css/imagePane.css").toExternalForm());
                RegionUtil.FxmlBean<VBox, ImagePageController> fxmlBean = RegionUtil.loadFxmlBean(this.getClass().getResource("/fxml/ImagePage.fxml"));
                fxmlBean.getController().setImMessage(message, !isRef && messageHandler != null);
                stage.setContent(fxmlBean.getNode());
                stage.show();
            });

            stackPane.getChildren().setAll(imageView);
            return stackPane;
        } catch (ImageNoDownloadException exception) {
            Label label = new Label("图片未下载");
            label.setPadding(new Insets(10, 5, 10, 5));
            if (!isRef) {
                label.setOnMouseClicked(e->{
                    RpcUtil.getImService().downloadFile(message, new DefaultFileProgressListener(), m-> UiUtil.uiUpdateMessage(m));
                });
            }
            return label;
        } catch (Exception e) {
            LOGGER.error("图片路径有问题：content: {}, path: {}", message.getContent(), imagePath);
            Label label = new Label("本地文件不存在");
            label.setPadding(new Insets(10, 5, 10, 5));
            return label;
        }
    }

    private void setImage(ImageView imageView, Image image, ImMessage message, boolean isRef) {
        if (message.getMessageExt() == null) {
            message.initExt();
        }
        double imageWidth = image.getWidth();
        double imageHeight = image.getHeight();
        double fitImageWidth = ImageUtil.calcFitImageWidth(ParamUtil.MESSAGE_WIDTH-100, imageWidth, imageHeight);
        double fitImageHeight = ImageUtil.calcFitImageHeight(fitImageWidth, imageWidth, imageHeight);
        imageView.setFitWidth(fitImageWidth);
        imageView.setFitHeight(fitImageHeight);

        if (isRef) {
            if (image.getHeight() > ParamUtil.MESSAGE_REF_HEIGHT) {
                imageView.setFitHeight(ParamUtil.MESSAGE_REF_HEIGHT);
            }
        } else {
            buildPopup(imageView, message);
        }
    }
}
